<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ZKFinger 指纹识别Web系统</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Microsoft YaHei', Arial, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .container {
            background: white;
            border-radius: 15px;
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
            padding: 30px;
            width: 90%;
            max-width: 1200px;
            min-height: 600px;
        }

        .header {
            text-align: center;
            margin-bottom: 30px;
            padding-bottom: 20px;
            border-bottom: 2px solid #f0f0f0;
        }

        .header h1 {
            color: #333;
            font-size: 28px;
            margin-bottom: 10px;
        }

        .status-indicator {
            display: inline-block;
            padding: 5px 15px;
            border-radius: 20px;
            font-size: 14px;
            font-weight: bold;
        }

        .status-connected {
            background: #4CAF50;
            color: white;
        }

        .status-disconnected {
            background: #f44336;
            color: white;
        }

        .main-content {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 30px;
            margin-bottom: 30px;
        }

        .control-panel {
            background: #f8f9fa;
            border-radius: 10px;
            padding: 20px;
        }

        .panel-title {
            font-size: 18px;
            font-weight: bold;
            color: #333;
            margin-bottom: 20px;
            text-align: center;
        }

        .form-group {
            margin-bottom: 15px;
        }

        .form-group label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            color: #555;
        }

        .form-group input {
            width: 100%;
            padding: 10px;
            border: 2px solid #ddd;
            border-radius: 5px;
            font-size: 14px;
            transition: border-color 0.3s;
        }

        .form-group input:focus {
            outline: none;
            border-color: #667eea;
        }

        .btn {
            padding: 12px 24px;
            border: none;
            border-radius: 5px;
            font-size: 14px;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.3s;
            margin: 5px;
            min-width: 120px;
        }

        .btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(0,0,0,0.2);
        }

        .btn-primary {
            background: #667eea;
            color: white;
        }

        .btn-success {
            background: #4CAF50;
            color: white;
        }

        .btn-danger {
            background: #f44336;
            color: white;
        }

        .btn-warning {
            background: #ff9800;
            color: white;
        }

        .btn:disabled {
            opacity: 0.6;
            cursor: not-allowed;
            transform: none;
        }

        .image-panel {
            text-align: center;
        }

        .fingerprint-display {
            width: 300px;
            height: 300px;
            border: 3px solid #ddd;
            border-radius: 10px;
            margin: 0 auto 20px;
            display: flex;
            align-items: center;
            justify-content: center;
            background: #f8f9fa;
            position: relative;
            overflow: hidden;
        }

        .fingerprint-display img {
            max-width: 100%;
            max-height: 100%;
            border-radius: 5px;
        }

        .placeholder-text {
            color: #999;
            font-size: 16px;
        }

        .log-panel {
            background: #2c3e50;
            border-radius: 10px;
            padding: 20px;
            height: 200px;
            overflow-y: auto;
            font-family: 'Consolas', monospace;
            font-size: 13px;
            color: #ecf0f1;
            line-height: 1.5;
        }

        .log-entry {
            margin-bottom: 5px;
            padding: 2px 0;
        }

        .log-timestamp {
            color: #95a5a6;
            margin-right: 10px;
        }

        .log-info { color: #3498db; }
        .log-success { color: #2ecc71; }
        .log-warning { color: #f39c12; }
        .log-error { color: #e74c3c; }

        .button-row {
            display: flex;
            justify-content: center;
            flex-wrap: wrap;
            margin-top: 20px;
        }

        @media (max-width: 768px) {
            .main-content {
                grid-template-columns: 1fr;
            }
            
            .container {
                padding: 20px;
                margin: 10px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🔐 ZKFinger 指纹识别Web系统</h1>
            <div class="status-indicator" id="deviceStatus">● 设备未连接</div>
        </div>

        <div class="main-content">
            <!-- 左侧控制面板 -->
            <div class="control-panel">
                <div class="panel-title">📝 指纹管理</div>
                
                <!-- 用户信息输入 -->
                <div class="form-group">
                    <label for="userId">用户ID:</label>
                    <input type="text" id="userId" placeholder="请输入用户ID">
                </div>
                
                <div class="form-group">
                    <label for="userName">用户姓名:</label>
                    <input type="text" id="userName" placeholder="请输入用户姓名">
                </div>

                <!-- 操作按钮 -->
                <div class="button-row">
                    <button class="btn btn-success" id="connectBtn">连接设备</button>
                    <button class="btn btn-danger" id="disconnectBtn" disabled>断开设备</button>
                </div>

                <div class="button-row">
                    <button class="btn btn-primary" id="enrollBtn" disabled>录入指纹</button>
                                            <button class="btn btn-warning" id="verifyBtn" disabled>连续验证</button>
                </div>

                <div class="button-row">
                    <button class="btn btn-danger" id="stopBtn" disabled>停止操作</button>
                </div>
            </div>

            <!-- 右侧图像显示 -->
            <div class="image-panel">
                <div class="panel-title">👆 指纹图像显示</div>
                <div class="fingerprint-display" id="fingerprintDisplay">
                    <div class="placeholder-text">等待指纹图像...</div>
                </div>
            </div>
        </div>

        <!-- 日志面板 -->
        <div class="panel-title">📋 系统日志</div>
        <div class="log-panel" id="logPanel">
            <div class="log-entry">
                <span class="log-timestamp">[启动]</span>
                <span class="log-info">系统初始化完成，等待连接指纹设备...</span>
            </div>
        </div>
    </div>

    <script>
        class FingerprintWebClient {
            constructor() {
                this.ws = null;
                this.isConnected = false;
                this.currentTemplate = null;
                this.initializeElements();
                this.bindEvents();
                this.connectWebSocket();
            }

            initializeElements() {
                this.elements = {
                    deviceStatus: document.getElementById('deviceStatus'),
                    userId: document.getElementById('userId'),
                    userName: document.getElementById('userName'),
                    connectBtn: document.getElementById('connectBtn'),
                    disconnectBtn: document.getElementById('disconnectBtn'),
                    enrollBtn: document.getElementById('enrollBtn'),
                    verifyBtn: document.getElementById('verifyBtn'),
                    stopBtn: document.getElementById('stopBtn'),
                    fingerprintDisplay: document.getElementById('fingerprintDisplay'),
                    logPanel: document.getElementById('logPanel')
                };
            }

            bindEvents() {
                this.elements.connectBtn.addEventListener('click', () => this.connectDevice());
                this.elements.disconnectBtn.addEventListener('click', () => this.disconnectDevice());
                this.elements.enrollBtn.addEventListener('click', () => this.enrollFingerprint());
                this.elements.verifyBtn.addEventListener('click', () => this.verifyFingerprint());
                this.elements.stopBtn.addEventListener('click', () => this.stopOperation());
            }

            connectWebSocket() {
                const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
                const wsUrl = `${protocol}//${window.location.host}/fingerprint-ws`;
                
                this.ws = new WebSocket(wsUrl);
                
                this.ws.onopen = () => {
                    this.log('WebSocket连接成功', 'success');
                };
                
                this.ws.onmessage = (event) => {
                    const message = JSON.parse(event.data);
                    this.handleMessage(message);
                };
                
                this.ws.onclose = () => {
                    this.log('WebSocket连接已断开', 'warning');
                    setTimeout(() => this.connectWebSocket(), 3000);
                };
                
                this.ws.onerror = (error) => {
                    this.log('WebSocket连接错误', 'error');
                };
            }

            handleMessage(message) {
                const { type, data } = message;
                
                switch (type) {
                    case 'message':
                        this.log(data);
                        break;
                    case 'image':
                        this.displayFingerprint(data);
                        break;
                    case 'template':
                        this.currentTemplate = data;
                        break;
                    case 'connect_result':
                        this.log(data, data.includes('成功') ? 'success' : 'error');
                        break;
                    case 'device_status':
                        this.updateDeviceStatus(data);
                        break;
                    case 'enroll_success':
                        this.handleEnrollSuccess(data);
                        break;
                    case 'verify_result':
                        if (data.includes('已停止')) {
                            this.log(`${data}`, 'info');
                            this.resetButtons();
                        } else {
                            this.log(`验证结果: ${data}`, data.includes('成功') ? 'success' : 'error');
                        }
                        break;
                    case 'error':
                        this.log(data, 'error');
                        break;
                }
            }

            sendMessage(action, data = {}) {
                if (this.ws && this.ws.readyState === WebSocket.OPEN) {
                    this.ws.send(JSON.stringify({ action, ...data }));
                }
            }

            connectDevice() {
                this.sendMessage('connect');
                this.elements.connectBtn.disabled = true;
            }

            disconnectDevice() {
                this.sendMessage('disconnect');
            }

            enrollFingerprint() {
                const userId = this.elements.userId.value.trim();
                const userName = this.elements.userName.value.trim();
                
                if (!userId || !userName) {
                    alert('请输入用户ID和姓名');
                    return;
                }
                
                this.sendMessage('enroll', { userId, userName });
                this.elements.enrollBtn.disabled = true;
                this.elements.stopBtn.disabled = false;
            }

            verifyFingerprint() {
                if (!this.currentTemplate) {
                    alert('请先录入指纹模板');
                    return;
                }
                
                this.log('开始连续验证模式，您可以连续验证多次指纹', 'info');
                this.sendMessage('verify', { template: this.currentTemplate });
                this.elements.verifyBtn.disabled = true;
                this.elements.stopBtn.disabled = false;
            }

            stopOperation() {
                this.sendMessage('stop');
                this.resetButtons();
            }

            updateDeviceStatus(connected) {
                this.isConnected = connected;
                const status = this.elements.deviceStatus;
                
                if (connected) {
                    status.textContent = '● 设备已连接';
                    status.className = 'status-indicator status-connected';
                } else {
                    status.textContent = '● 设备未连接';
                    status.className = 'status-indicator status-disconnected';
                }
                
                this.updateButtonStates();
            }

            updateButtonStates() {
                this.elements.connectBtn.disabled = this.isConnected;
                this.elements.disconnectBtn.disabled = !this.isConnected;
                this.elements.enrollBtn.disabled = !this.isConnected;
                this.elements.verifyBtn.disabled = !this.isConnected || !this.currentTemplate;
                this.elements.stopBtn.disabled = true;
            }

            resetButtons() {
                this.updateButtonStates();
            }

            handleEnrollSuccess(data) {
                this.currentTemplate = data.template;
                this.log(`用户 ${data.userName} 的指纹录入成功！`, 'success');
                this.resetButtons();
            }

            displayFingerprint(base64Image) {
                const img = document.createElement('img');
                img.src = `data:image/bmp;base64,${base64Image}`;
                img.alt = '指纹图像';
                
                this.elements.fingerprintDisplay.innerHTML = '';
                this.elements.fingerprintDisplay.appendChild(img);
            }

            log(message, type = 'info') {
                const timestamp = new Date().toLocaleTimeString();
                const logEntry = document.createElement('div');
                logEntry.className = 'log-entry';
                
                logEntry.innerHTML = `
                    <span class="log-timestamp">[${timestamp}]</span>
                    <span class="log-${type}">${message}</span>
                `;
                
                this.elements.logPanel.appendChild(logEntry);
                this.elements.logPanel.scrollTop = this.elements.logPanel.scrollHeight;
            }
        }

        // 启动应用
        document.addEventListener('DOMContentLoaded', () => {
            new FingerprintWebClient();
        });
    </script>
</body>
</html> 